﻿using AForge.Video.DirectShow;
using AForge.Video.FFMPEG;
using CCWin;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Counter
{
    public partial class frmCap : CCSkinMain
    {
        /// <summary>
        /// 视频采集装置列表
        /// </summary>
        private FilterInfoCollection videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
        /// <summary>
        /// 表示当前监控窗体绑定的视频监控器实例
        /// </summary>
        private VideoCaptureDevice selectedDevice;
        /// <summary>
        /// 表示录像路径
        /// </summary>
        private string videoFileName;
        /// <summary>
        /// 表示是否开始录像
        /// </summary>
        private bool startCap = false;
        /// <summary>
        /// 表示视频写入器
        /// </summary>
        private VideoFileWriter videoWriter;
        /// <summary>
        /// 表示是否需要重新创建录像文件
        /// </summary>
        private bool createNewFile = true;
        /// <summary>
        /// 默认帧率
        /// </summary>
        private int frameRate = 100;
        /// <summary>
        /// 表示已录制的帧数
        /// </summary>
        private long frameCount = 0;
        /// <summary>
        /// 表示开始录制的时间
        /// </summary>
        private DateTime startRecTime;
        /// <summary>
        /// 表示开始时间
        /// </summary>
        private TimeSpan startTime;
        /// <summary>
        /// 是否为备用录像窗口
        /// </summary>
        public bool isBackup = false;
        /// <summary>
        /// 备用录像窗口
        /// </summary>
        private frmCap cap;
        public frmCap(bool isBackup)
        {
            InitializeComponent();
            //填充视频采集装置列表
            tcomVideoSources.Items.Clear();
            string defMainName = Program.setting.ReadString("VideoSource", "main", "");
            string defBakName = Program.setting.ReadString("VideoSource", "backup", "");
            foreach (FilterInfo info in videoDevices)
            {
                tcomVideoSources.Items.Add(info.Name);
                if (!isBackup)
                {
                    if (info.Name == defMainName || info.Name == defBakName)
                    {
                        tcomVideoSources.SelectedIndex = tcomVideoSources.Items.Count - 1;
                        if (info.Name == defBakName)
                        {
                            SetBackup();
                        }
                    }
                }
            }
            if (tcomVideoSources.Items.Count > 0)
            {
                tcomVideoSources.SelectedIndex = 0;
            }
            this.isBackup = isBackup;
        }

        private void formCap_Load(object sender, EventArgs e)
        {
            if (isBackup)
            {
                this.Height = 100;
                this.groupBox1.Visible = false;
                this.toolStripButton1.Visible = false;
            }
            this.tcomVideoSources.Focus(); 
            //最大化窗口
            this.WindowState = FormWindowState.Maximized; 
        }

        private void tbtnConnect_Click(object sender, EventArgs e)
        {
            try
            {
                FilterInfo selectedFilter = videoDevices[this.tcomVideoSources.SelectedIndex];
                Program.setting.WriteString("VideoSource", isBackup ? "backup" : "main", selectedFilter.Name);
                this.tlabelStatu.Text = "正在连接设备 " + selectedFilter.Name + "...";
                selectedDevice = new VideoCaptureDevice(selectedFilter.MonikerString);
                if (this.vplayerCapVideo.VideoSource != null)
                {
                    this.vplayerCapVideo.Stop();
                }
                this.vplayerCapVideo.VideoSource = selectedDevice;
                this.vplayerCapVideo.Start();
                this.toolsCapSetting.Enabled = true;
                this.tbtnDisconnect.Enabled = true;
                this.tbtnConnect.Enabled = false;
                this.tlabelStatu.Text = "连接设备 " + selectedFilter.Name + " 成功！";
                videoFileName = Application.StartupPath + "/Rec/" + (isBackup ? "_bak" : "") + "/" + DateTime.Now.ToString("yyyy.MM.dd HH.mm.ss") + ".avi";
                startCap = true;
                tbtnStartCap.Enabled = true;
                tbtnStopCap.Enabled = false;
                toolStripButton1.Enabled = false;
                startRecTime = DateTime.Now;
                frameCount = 0;
                timerRecInfo.Start();
                if (cap != null)
                {
                    Thread.Sleep(500);
                    cap.tbtnConnect_Click(sender, e);
                }
                this.vplayerCapVideo.Focus();
            }
            catch (Exception ex)
            {
                MessageBox.Show("连接设备 " + this.tcomVideoSources.Text + " 失败：" + ex.Message);
                this.tlabelStatu.Text = "连接设备 " + this.tcomVideoSources.Text + " 失败：" + ex.Message;
            }
        }

        private void formCap_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                this.vplayerCapVideo.Stop();
            }
            catch (Exception)
            {
            }
        }

        private void tbtnDisconnect_Click(object sender, EventArgs e)
        {
            try
            {
                this.tlabelStatu.Text = "正在断开设备 " + this.tcomVideoSources.Text + "...";
                if (this.vplayerCapVideo.VideoSource != null)
                {
                    this.vplayerCapVideo.Stop();
                }
                this.tbtnConnect.Enabled = true;
                this.tbtnDisconnect.Enabled = false;
                this.toolsCapSetting.Enabled = false;
                toolStripButton1.Enabled = true;
                this.tlabelStatu.Text = "断开设备 " + this.tcomVideoSources.Text + " 成功！";
                if (cap != null)
                {
                    cap.tbtnDisconnect_Click(cap.tbtnDisconnect, null);
                    cap.Dispose();
                    cap = null;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("断开设备失败：" + ex.Message);
                this.tlabelStatu.Text = "断开设备失败：" + ex.Message;
            }

        }

        private void tbtnStartCap_Click(object sender, EventArgs e)
        {
            startTime = DateTime.Now - startRecTime - new TimeSpan(0, 0, 0, 0, 200);
            this.tbtnStartCap.Text = "开始时间：" + startTime.ToString();
            this.tbtnStartCap.Enabled = false;
            tbtnStopCap.Enabled = true;
        }

        private void tbtnStopCap_Click(object sender, EventArgs e)
        {
            startCap = false;
            tbtnStopCap.Enabled = false;
            tbtnStartCap.Enabled = false;
            toolsVideoSource.Enabled = true;
            if (videoWriter != null)
            {
                videoWriter.Close();
                videoWriter.Dispose();
            }
            createNewFile = true;
            videoWriter = null;
            timerRecInfo.Stop();
            this.tlabelStatu.Text = "录制文件路径：" + videoFileName;
            if (cap != null)
            {
                cap.tbtnStopCap_Click(sender, e);
            }
            if (!isBackup)
            {

                if (cap != null)
                {
                    cap.Dispose();
                }
                this.vplayerCapVideo.Stop();
                this.Dispose();
                frmCount cForm = new frmCount();
                cForm.startTime = this.startTime;
                cForm.Show();
            }
        }

        private void vplayerCapVideo_NewFrame(object sender, ref Bitmap image)
        {
            if (!Directory.Exists(Application.StartupPath + "/Rec/" + (isBackup ? "_bak" : "") + "/"))
                Directory.CreateDirectory(Application.StartupPath + "/Rec/" + (isBackup ? "_bak" : "") + "/");

            if (startCap)
            {
                //开始录像
                //为图片加上日期
                using (Graphics g = Graphics.FromImage(image))
                {
                    g.DrawString("Time:" + DateTime.Now.ToLongTimeString() + ",REC:" + (DateTime.Now - startRecTime).ToString("g"), Font, Brushes.Red, new PointF(0f, 0f));
                }
                if (createNewFile)
                {
                    createNewFile = false;
                    if (videoWriter != null)
                    {
                        videoWriter.Close();
                        videoWriter.Dispose();
                    }
                    videoWriter = new VideoFileWriter();
                    //这里必须是全路径，否则会默认保存到程序运行根据录下了
                    videoWriter.Open(videoFileName, image.Width, image.Height, frameRate, VideoCodec.MPEG4);

                    videoWriter.WriteVideoFrame(image, DateTime.Now - startRecTime);

                }
                else
                {
                    videoWriter.WriteVideoFrame(image, DateTime.Now - startRecTime);
                }
                frameCount++;
            }
        }

        private void timerRecInfo_Tick(object sender, EventArgs e)
        {
            tlabelStatu.Text = "录制时间：" + (DateTime.Now - startRecTime).ToString("g") + "，已录制帧数：" + frameCount;
        }

        private void frmCap_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
            {
                if(tbtnConnect.Enabled)
                    tbtnConnect_Click(tbtnConnect, null);
            }
            else if (e.KeyChar == 32)
            {
                if(tbtnStartCap.Enabled)
                    tbtnStartCap_Click(tbtnStartCap, null);
            }
            else if(e.KeyChar == 27)
            {
                if(tbtnStopCap.Enabled)
                    tbtnStopCap_Click(tbtnStopCap, null);
            }
        }

        private void frmCap_FormClosed(object sender, FormClosedEventArgs e)
        {
            Program.mainForm.Show();
            this.Dispose();
            if (!isBackup)
            {

                if (cap != null)
                {
                    cap.tbtnStopCap_Click(cap.tbtnStopCap, null);
                }
            }
        }
        void SetBackup()
        {
            cap = new frmCap(true);
            cap.isBackup = true;
            cap.tcomVideoSources.SelectedIndex = this.tcomVideoSources.SelectedIndex;
            this.toolStripButton1.Text = "备用录像源：" + cap.tcomVideoSources.Text;
            this.toolStripButton1.Enabled = false;
        }
        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            SetBackup();
            MessageBox.Show("设置为备用录像源成功！", "温馨提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void frmCap_Shown(object sender, EventArgs e)
        {

        }

        private void tcomVideoSources_KeyPress(object sender, KeyPressEventArgs e)
        {

        }
    }
}
